package com.jcroke.PC32.parser;

import java.lang.reflect.Constructor;
import java.util.ArrayList;
import java.util.Hashtable;
import java.util.LinkedHashMap;

import com.jcroke.DACGraph.Pnode;
import com.jcroke.DACGraph.Signature;
import com.jcroke.PC32.basetransform.DefaultTransformer;
import com.jcroke.PC32.datum.Datum;
import com.jcroke.PC32.exception.ParserException;


public class SimpleDelimiterParser extends DefaultTransformer {

	// Input tags
	public final String RECORD_IN = "record_in";
	public final String ORDERED_TAG_NAMES_IN = "orderedTagNames_in";
	public final String PARSER_ARG0_IN = "parser_arg0_in";

	private Hashtable<String, Constructor<?>> types = new Hashtable<String, Constructor<?>>();
	private LinkedHashMap<String, Datum> input;
	private String[] tags;

	@Override
	public void prepare(Pnode pnode) {
		super.prepare(pnode);
		// Get hash map of tags and types
		ArrayList<Signature> sA = pNode().getOutputSignature();
		for (Signature s : sA) {
			try {
				types.put(
						s.getSourcePin(),
						Class.forName(s.getSourceTypeClass()).getConstructor(
								String.class));
			} catch (SecurityException e) {
				e.printStackTrace();
			} catch (NoSuchMethodException e) {
				e.printStackTrace();
			} catch (ClassNotFoundException e) {
				e.printStackTrace();
			}
		}

		input = getInput();

		// Get the output tag (address) list
		String tagList = input.get(ORDERED_TAG_NAMES_IN).toString();
		tags = tagList.split("\\s*,\\s*");

	}

	public void execute() {
		// Make a bunch of datums from the strings. The field order will
		// be applied in the same order as the tag list.
		String record = (String) input.get(RECORD_IN).toString();
		String[] elements = record.split(input.get(PARSER_ARG0_IN).toString());
		Hashtable<String, Datum> dOut = new Hashtable<String, Datum>();

		for (int i = 0; i < elements.length; i++) {
			String tag = tags[i];
			String value = elements[i];
			try {
				dOut.put(tag, (Datum) types.get(tag).newInstance(value));
			} catch (Exception e) {
				throw new ParserException(
						"SimpleDelimterParser Could not create instantiate datum type for tag: "
								+ tag + " type: " + types.get(tag), e);
			}
		}
		emit(dOut);
	}
}
